/* The Computer Language Benchmarks Game
   https://salsa.debian.org/benchmarksgame-team/benchmarksgame/

   Converted to Kotlin/Native compatible version
   Maintains original logic and output consistency
 */

import kotlin.math.sqrt
import kotlin.system.getTimeNanos

object SampleSpectralNorm {
    // 自定义数字格式化函数，不依赖String.format
    private fun formatNumber(value: Double): String {
        val integerPart = value.toInt()
        val fractionalPart = (value - integerPart) * 1000000000 + 0.5 // 四舍五入
        val fractionalStr = fractionalPart.toLong().toString()

        // 确保小数部分有9位，不足补零
        val padded = if (fractionalStr.length < 9) {
            "0".repeat(9 - fractionalStr.length) + fractionalStr
        } else {
            fractionalStr.substring(0, 9)
        }

        return "$integerPart.$padded"
    }

    // 自定义时间格式化函数
    private fun formatTime(value: Double): String {
        val integerPart = value.toInt()
        val fractionalPart = (value - integerPart) * 1000 + 0.5 // 保留三位小数
        val fractionalStr = fractionalPart.toInt().toString()

        // 确保小数部分有3位，不足补零
        val padded = when (fractionalStr.length) {
            1 -> "${fractionalStr}00"
            2 -> "${fractionalStr}0"
            else -> fractionalStr.substring(0, 3)
        }

        return "$integerPart.$padded"
    }

    fun main(args: Array<String>) {
        for (i in 1..1) {
            val one = getTimeNanos()
            main_(args)
            val two = getTimeNanos()
            println(formatTime((two - one) / 1.0e9))
        }
    }

    private fun main_(args: Array<String>) {
        var n = 100
        if (args.isNotEmpty()) {
            n = args[0].toInt()
        }
        println(formatNumber(approximate(n)))
    }

    private fun approximate(n: Int): Double {
        // Create unit vector
        val u = DoubleArray(n) { 1.0 }

        // 20 steps of the power method
        val v = DoubleArray(n) { 0.0 }

        repeat(10) {
            multiplyAtAv(n, u, v)
            multiplyAtAv(n, v, u)
        }

        // Calculate v.Bv / (v.v) where B = AtA
        var vBv = 0.0
        var vv = 0.0
        for (i in 0 until n) {
            vBv += u[i] * v[i]
            vv += v[i] * v[i]
        }

        return sqrt(vBv / vv)
    }

    /* Return element i,j of infinite matrix A */
    private fun a(i: Int, j: Int): Double {
        val denom = (i + j) * (i + j + 1) / 2 + i + 1
        return 1.0 / denom
    }

    /* Multiply vector v by matrix A */
    private fun multiplyAv(n: Int, v: DoubleArray, av: DoubleArray) {
        for (i in 0 until n) {
            av[i] = 0.0
            for (j in 0 until n) {
                av[i] += a(i, j) * v[j]
            }
        }
    }

    /* Multiply vector v by matrix A transposed */
    private fun multiplyAtv(n: Int, v: DoubleArray, atv: DoubleArray) {
        for (i in 0 until n) {
            atv[i] = 0.0
            for (j in 0 until n) {
                atv[i] += a(j, i) * v[j]
            }
        }
    }

    /* Multiply vector v by matrix A and then by matrix A transposed */
    private fun multiplyAtAv(n: Int, v: DoubleArray, atAv: DoubleArray) {
        val u = DoubleArray(n)
        multiplyAv(n, v, u)
        multiplyAtv(n, u, atAv)
    }
}

// Kotlin/Native 程序入口点
fun main(args: Array<String>) {
    SampleSpectralNorm.main(args)
}
